/*
 * Copyright (C) 2011 Nicola Bonzanni
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package nl.vu.few.ibivu.jlemon.concepts;

public interface Graph<N extends Node & Comparable<N>, A extends Arc & Comparable<A>> {
	/**
	 * 
	 * @param arc
	 * @return the source node of the given arc
	 */
	N source(A arc);
	/**
	 * 
	 * @param arc
	 * @return the target node of the given arc
	 */
	N target(A arc);
	/**
	 * 
	 * @param node
	 * @return the ID of the given node or -1 if the node doesn't belong to this graph
	 */
	int id(N node);
	/**
	 * 
	 * @param arc
	 * @return the ID of the given arc or -1 if the arc doesn't belong to this graph
	 */
	int id(A arc);
	/**
	 * 
	 * @param id the node ID
	 * @return the node with the given ID or null if the ID is not a valid node ID for this graph
	 */
	N nodeFromId(int id);
	/**
	 * 
	 * @param id the arc ID
	 * @return the arc with the given ID or null if the ID is not a valid arc ID for this graph
	 */
	A arcFromId(int id);
	/**
	 * 
	 * @return an upper bound on the node IDs
	 */
	int maxNodeId();
	/**
	 * 
	 * @return an upper bound on the arc IDs
	 */
	int maxArcId();
	/**
	 * 
	 * @return the total number of nodes in the graph
	 */
	int nodeNum();
	/**
	 * 
	 * @return the total number of arcs in the graph
	 */
	int arcNum();
	/**
	 * Returns the node opposite to the given {@code node} on the given arc.
	 * @param node
	 * @param arc
	 * @return the node opposite to the given {@code node} on the given arc
	 */
	N oppositeNode(N node, A arc);
	/**
	 * TODO
	 * @param node
	 * @return
	 */
	A firstOut(N node);
	/**
	 * 
	 * @param arc
	 * @return
	 */
	A nextOut(A arc);
	/**
	 * 
	 * @return the first {@code Node} of this graph instance if any,
	 *         {@code null} otherwise
	 */
	N firstNode();
	/**
	 * 
	 * @param node
	 *            a valid node of this graph instance
	 * @return the {@code Node} next to {@code node} or {@code null} if
	 *         {@code node} is the last
	 */
	N next(N node);
	/**
	 * 
	 * @return the first {@code Arc} of this graph instance if any, {@code null}
	 *         otherwise
	 */
	A firstArc();
	/**
	 * 
	 * @param arc
	 *            a valid arc of this graph instance
	 * @return
	 */
	A next(A node);
	/**
	 * TODO
	 * @param node
	 * @return
	 */
	A firstIn(N node);
	/**
	 * TODO
	 * @param arc
	 * @return
	 */
	A nextIn(A arc);
	/**
	 * Returns the Class type of the node used in this graph instance
	 * @return the Class type of the node used in this graph instance
	 */
	Class<N> getNodeClass();
	/**
	 * Returns the Class type of the arc used in this graph instance
	 * @return the Class type of the arc used in this graph instance
	 */
	Class<A> getArcClass();
}
